// Copyright 2019 The rhyme_lph Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// T [author] rhyme_lph
// j [email]  rhymelph@gmail.com
// s [github] https://github.com/rhymelph

import 'package:base_plugin/base_plugin.dart';
import 'package:finance_app/generated/l10n.dart';
import 'package:finance_app/src/entities/coa_entity.dart';
import 'package:finance_app/src/http_service/http_coa_service.dart';
import 'package:finance_app/src/mixin/search_data_list_mixin.dart';
import 'package:finance_app/src/provider/setting/chart_of_accounts_provider.dart';
import 'package:finance_app/src/router_gen/router_gen_providers.dart';
import 'package:finance_app/src/widgets/bottom_sheet/got_it_info_bottom_sheet.dart';
import 'package:finance_app/src/widgets/bottom_sheet/got_it_tip_bottom_sheet.dart';
import 'package:flutter/material.dart';

class SetOpeningBalanceProvider extends BaseProvider<List<CoaByGroupEntity>>
    with SearchDataListMixin {
  Map<int, String> updateOldMap = {};

  String currencyCode;

  @override
  Future get dataFuture => HttpCoaService.coaNewList();

  double debitTotal = 0.00;

  double creditTotal = 0.00;

  double difference = 0.00;

  List<int> parentIDs = [];

  @override
  void searchRefreshData(searchData) {}

  void formatTotal(List<CoaByGroupEntity> d, {bool isUpdate = false}) {
    double _dTotal = 0.0;
    double _cTotal = 0.0;
    for (final item in d) {
      for (final item1 in item?.coaAccountDetail) {
        if (item1.accountCode == '3200') continue;

        if (parentIDs.contains(item1.id) && item1.parentAccountId == 0) {
          item1.hardValue = item.coaAccountDetail
              .where((element) => element.parentAccountId == item1.id)
              .map((e) => e.openBalance)
              .reduce((a, b) => a + b);
          continue;
        }

        if (item1.crdrNature == 'DR') {
          _dTotal += item1.openBalance;
        } else {
          _cTotal += item1.openBalance;
        }
      }
    }
    debitTotal = _dTotal;
    creditTotal = _cTotal;
    difference = debitTotal - creditTotal;
    if (isUpdate == true) update();
  }

  void updateValue(
      CoaCoaAccountHeaderCoaAccountDetail detail, String dataString) {
    if (dataString == detail.openBalance.toString()) return;
    int id = detail.id;
    if (!updateOldMap.containsKey(id)) {
      updateOldMap[id] = detail.openBalance.toString();
    } else if (updateOldMap[id] == detail.openBalance.toString()) {
      updateOldMap.remove(id);
    }
    detail.openBalance = num.parse(dataString, (e) => 0.0);
    formatTotal(data, isUpdate: true);
    // update();
  }

  void onSave() async {
    FocusManager.instance.primaryFocus.unfocus();
    if (difference != 0.0) {
      obtainContext?.call((context) {
        showCOABalanceNotEqualInfoBottomSheet(context);
      });
      return;
    }

    if (updateOldMap.isNotEmpty) {
      List lines = [];
      for (final i in data) {
        for (final i2 in i.coaAccountDetail) {
          if (updateOldMap[i2.id] != null) {
            lines.add({
              'id': i2.id,
              'open_balance': i2.openBalance,
            });
          }
        }
      }
      bool isSuccess = false;
      await post(HttpCoaService.setOpeningBalance(lines),
          autoHandler: AutoHandler.Toast,
          loadingTip: S.current.loading, onSuccess: (result) {
        isSuccess = true;
      });
      if (isSuccess == true) {
        obtainContext?.call((context) async {
          await showUpdateBalancesSuccessTipBottomSheet(context);
          Providers.get<ChartOfAccountsProvider>(
                  RouterGenProviders.chartOfAccountsPage, null)
              ?.onTry();
          Navigator.of(context).pop();
        });
      }
    }
  }

  void onCancel() {
    obtainContext?.call((context) async {
      Navigator.pop(context);
    });
  }

  @override
  FutureOr<List<CoaByGroupEntity>> transformData(
      List<CoaByGroupEntity> d, bool isCache) {
    for (var item in d) {
      parentIDs.addAll(item.coaAccountDetail
          .map((e) => e.parentAccountId)
          .where((parentId) => parentId != 0)
          .toSet()
          .toList());
    }

    formatTotal(d);

    return super.transformData(d, isCache);
  }
}
